package edu.ynu.e_platform.service;

import edu.ynu.e_platform.common.service.LogicService;
import edu.ynu.e_platform.dao.*;
import edu.ynu.e_platform.entities.*;
import edu.ynu.e_platform.entities.Customer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author manwen Yang
 */
@Slf4j
@Service
public class CustomerService extends LogicService<CustomerDao, Customer, Long> {

    @Resource
    UserDao userDao;

    @Resource
    ShopDao shopDao;

    @Resource
    ShopItemDao shopItemDao;

    @Resource
    OrderDao orderDao;

    @Resource
    ItemDao itemDao;

    @Resource
    LineItemDao lineItemDao;

    /**
     * @Autowired 自动注入需要的dao
     * */
    public CustomerService(@Autowired CustomerDao lr) {
        super(lr);
    }

    public Customer enroll(String userName, String password, Integer sex){

        User tem = null;
        Customer customer = new Customer();
        customer.setUsername(userName);
        customer.setPassword(password);
        customer.setSex(sex);

        try {
            tem = userDao.findByUsername(userName);
            //如果该用户名已被注册，返回空，说明注册失败
            if(tem != null){
                return null;
            } else{
                customer = getDAO().save(customer);
                return customer;
            }

        } catch (Exception e) {
            log.warn(e.toString());
        }

        return null;
    }

    /**
     * 客户挑选商品
     * */
    public Order pickItem(Long userId, Long shopItemId, Double quantity){

        try {
            ShopItem shopItem = shopItemDao.getReferenceById(shopItemId);
            Item item = itemDao.getReferenceById(shopItem.getItem().getId());
            Shop shop = shopDao.getReferenceById(shopItem.getShop().getId());
            Customer customer = GET(userId);

            Order order = customer.createOreder(shop);
            order = orderDao.save(order);
            LineItem lineItem = order.addItem(item, quantity);
            lineItem = lineItemDao.save(lineItem);
            //计算商品总价
            order.setTotalPrice();
            order = orderDao.save(order);

            return order;

        } catch (Exception e) {
            log.warn(e.toString());
        }
        return null;
    }

    /**
     * 客户支付订单
     * */
    public Order payment(Long userId, Long orderId){

        Customer customer = null;
        Order order = null;

        try {
            customer = GET(userId);
            order = orderDao.getReferenceById(orderId);

            order = customer.payOrder(order);
            order = orderDao.save(order);

        } catch (Exception e) {
            log.warn(e.toString());
        }

        return order;
    }

    /**
     * 客户取消订单
     * */
    public Boolean cancelOrder(Long userId, Long orderId){

        Customer customer = null;
        Order order = null;

        try {
            customer = GET(userId);
            order = orderDao.getReferenceById(orderId);

            //未支付的订单才能删除
            if (order.getStatus().equals(0)) {
                orderDao.delete(order);
                return true;
            }

            System.out.println("订单已支付，无法取消！");

        } catch (Exception e) {
            log.warn(e.toString());
        }

        return false;
    }

    /**
     * 客户查询所有订单
     * */
    public List<Order> queryOrders(Long userId){

        Customer customer = null;
        List<Order> results = null;

        try {
            customer = GET(userId);
            results = orderDao.findByCustomer(customer);

            return results;
        } catch (Exception e) {
            log.warn(e.toString());
        }

        return null;

    }

    /**
     * 客户查询未支付订单
     * */
    public List<Order> queryOrderUnpay(Long userId){

        Customer customer = null;
        List<Order> results = null;

        try {
            customer = GET(userId);
            results = orderDao.findByCustomerAndStatus(customer, 0);

            return results;
        } catch (Exception e) {
            log.warn(e.toString());
        }

        return null;
    }

    /**
     * 客户查询已支付订单
     * */
    public List<Order> queryOrderPay(Long userId){

        Customer customer = null;
        List<Order> results = null;
        List<Order> results2 = null;

        try {
            customer = GET(userId);
            results = orderDao.findByCustomerAndStatus(customer, 1);
            //已确认的订单也算支付过
            results2 = orderDao.findByCustomerAndStatus(customer, 2);

            results.addAll(results2);

            return results;
        } catch (Exception e) {
            log.warn(e.toString());
        }

        return null;
    }

    /**
     * 分页查询未支付订单
     * */
    public Page<Order> pageQueryOrderUnpay(Integer pageStart,
                                              Integer pageSize,
                                              Long userId){

        Customer customer = null;

        try {
            customer = getDAO().getReferenceById(userId);
            Pageable pageable = PageRequest.of(pageStart, pageSize, Sort.by("createTime").descending());

            return orderDao.pageFind(customer, 0, pageable);
        } catch (Exception e) {
            log.warn(e.toString());
        }

        return null;
    }

    /**
     * 分页查询已支付订单
     * */
    public Page<Order> pageQueryOrderPay(Integer pageStart,
                                              Integer pageSize,
                                              Long userId){

        Customer customer = null;

        try {
            customer = getDAO().getReferenceById(userId);
            Pageable pageable = PageRequest.of(pageStart, pageSize, Sort.by("createTime").descending());

            var results = orderDao.pageFindPay(customer, pageable);

            return results;
        } catch (Exception e) {
            log.warn(e.toString());
        }

        return null;
    }
}
